package com.biemo.cloud.bbs.core.upload;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.biemo.cloud.bbs.core.upload.bean.UploadBean;
import com.biemo.cloud.bbs.modular.context.BiemoLoginContext;
import com.biemo.cloud.bbs.modular.domain.BAttachment;
import com.biemo.cloud.bbs.modular.domain.BUser;
import com.biemo.cloud.bbs.modular.service.IBAttachmentService;
import com.biemo.cloud.bbs.utils.ControllerUtil;
import com.biemo.cloud.bbs.utils.PathUtil;
import com.biemo.cloud.bbs.utils.QiniuUtil;
import com.biemo.cloud.core.util.DateUtils;
import com.biemo.cloud.core.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.UUID;

import static com.sun.org.apache.xerces.internal.impl.dv.util.Base64.decode;

/**
 * Description:
 *
 * @author BIEMO
 * @create 2017-07-19
 **/
@Component
@Scope("prototype")
public class UploadComponent {


    @Value("${virtual.path.enable}")
    String enableVirtualPath;

    @Value("${virtual.path.windows}")
    String windowsUploadPath;

    @Value("${virtual.path.linux}")
    String linuxUploadPath;

    @Value("${qiniu.accessKey}")
    private String accessKey;

    @Value("${qiniu.secretKey}")
    private String secretKey;

    @Value("${qiniu.bucketname}")
    private String bucketname;

    @Value("${qiniu.cdnDomain}")
    private String domain;

    @Value("${qiniu.upload.enable}")
    private String qiniuUpload;

    @Value("virtual.path.enableFullPath")
    private String enableFullPath = "false";

    @Autowired
    IBAttachmentService attachmentService;


    public UploadBean uploadFile(MultipartFile multipartFile, HttpServletRequest request){
        if (!multipartFile.isEmpty()) {
            BAttachment attachment = new BAttachment();
            /** 获取用户会话 **/
            BUser userVo  = BiemoLoginContext.me().getCurrentUser();
            if(userVo!=null) {
                attachment.setUserId(userVo.getId().toString());
                attachment.setUserName(userVo.getUsername());
            }
            attachment.setUploadDate(new Date());
            attachment.setUploadIp(ControllerUtil.getRemoteAddress(request));
            attachment.setFileSize(Float.valueOf(multipartFile.getSize())/1024);
            attachment.setFileExtname(multipartFile.getContentType());
            attachment.setFileKey(UUID.randomUUID().toString().replace("-",""));
            attachment.setOriginalFileName(multipartFile.getOriginalFilename());
            /*创建uploadBean*/
            UploadBean result = new UploadBean();
            String fileType = this.getFileType(attachment.getOriginalFileName());
            String fileName = this.getFileName(fileType) ;
            String newName =this.getNewFileName(fileName);
            if (!Boolean.parseBoolean(qiniuUpload)) {
                File file = new File(this.getUploadPath() + newName);
                /*如果不存在就创建*/
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }
                try {
                    this.writeFile(multipartFile.getBytes(), file);
                    attachment.setFilePath(newName);
                    attachment.setFileName(fileName);
                    if(Boolean.parseBoolean(enableFullPath)) {
                        result.setUrl(request.getScheme() + "://" + ControllerUtil.getDomain() + "/res/" + attachment.getFileKey() + "." + fileType);
                    }else {
                        result.setUrl("/res/" + attachment.getFileKey() + "." + fileType);

                    }
                    attachmentService.save(attachment);
                } catch (Exception e) {
                    throw new RuntimeException(e.getMessage());
                }
            }else {
                String qiniuFileResult = QiniuUtil.upload(accessKey, secretKey, bucketname, multipartFile);
                if (!StrUtil.isBlank(qiniuFileResult)) {
                    String fileKey = JSON.parseObject(qiniuFileResult).getString("key");
                    String fileUrl = domain + "/" + fileKey;
                    //result.setPreview(fileUrl+"?imageView2/0/w/180/h/180/q/75");
                    result.setPreview(fileUrl+"?imageMogr2/thumbnail/180x180/format/webp/blur/1x0/quality/75");
                    if (com.biemo.cloud.core.util.StringUtils.getExtensionName(fileName).equals("jpg") || StringUtils.getExtensionName(fileName).equals("JPG") || StringUtils.getExtensionName(fileName).equals("png") || StringUtils.getExtensionName(fileName).equals("PNG") || StringUtils.getExtensionName(fileName).equals("jpeg") ||StringUtils.getExtensionName(fileName).equals("JPEG")) {
                        fileUrl += "?imageslim";
                    }
                    result.setUrl(fileUrl);
                }
            }
            return result;
        }else{
            throw new RuntimeException("上传文件不能为空！");
        }
    }

    public String getUploadPath(){
        String os = System.getProperty("os.name");
        String uploadPath = enableVirtualPath.equals("true")
                ?(os.toLowerCase().startsWith("win")
                ?windowsUploadPath
                :linuxUploadPath)
                : PathUtil.getRootClassPath()+ File.separator + "static";
        return uploadPath;
    }

    public Charset getCharset(){
        String os = System.getProperty("os.name");
        Charset charset = os.toLowerCase().startsWith("win")
                ? Charset.forName("gbk")
                :Charset.forName("UTF-8");
        return charset;
    }
    public  UploadBean uploadBase64File(String data, HttpServletRequest request){

        /*创建uploadBean*/
        UploadBean result = new UploadBean();
        if (!StringUtils.isBlank(data)) {
            BAttachment attachment = new BAttachment();
            BUser userVo  = BiemoLoginContext.me().getCurrentUser();
            if(userVo!=null) {
                attachment.setUserId(userVo.getId().toString());
                attachment.setUserName(userVo.getUsername());
            }
            attachment.setUploadDate(new Date());
            attachment.setUploadIp(ControllerUtil.getRemoteAddress(request));
            attachment.setFileSize(this.getBase64FileSize(data).floatValue()/1024);
            if(getBase64FileType(data).equals("png")){
               attachment.setFileExtname("image/png");
            }else if(getBase64FileType(data).equals("gif")){
                attachment.setFileExtname("image/gif");
            }else if(getBase64FileType(data).equals("jpg")){
                attachment.setFileExtname("image/jpeg");
            }
            attachment.setFileKey(UUID.randomUUID().toString().replace("-",""));
           String fileType = this.getBase64FileType(data);
           String fileName = this.getFileName(fileType);
           String newName = this.getNewFileName(fileName);
            attachment.setOriginalFileName(newName);
            File file = new File(this.getUploadPath() + newName);
            attachment.setFilePath(file.getPath());
            attachment.setFileName(fileName);
            /*如果不存在就创建*/
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            try {
                this.writeFile(this.base64StrToByte(data),file);
            } catch (Exception e) {
                throw  new RuntimeException(e.getMessage());
            }
            if(Boolean.parseBoolean(enableFullPath)) {
                result.setUrl(request.getScheme() + "://" + ControllerUtil.getDomain() + "/res/" + attachment.getFileKey() + "." + fileType);
            }else {
                result.setUrl("/res/" + attachment.getFileKey() + "." + fileType);

            }
            return result;
        }else{
                throw new RuntimeException("上传文件不能为空！");
        }
    }

    public  String getFileName(String fileType){
      return UUID.randomUUID().toString().replace("-","") + "." + fileType;
    }

    public  String getZipFileName(String fileName){
        return File.separator + "upload" + File.separator +"ebook"+File.separator + DateUtils.getYears()
                + File.separator + DateUtils.getMonth() + File.separator + DateUtils.getDay() + File.separator + fileName;
    }

    public  String getNewFileName(String fileName){
        return File.separator + "upload" + File.separator + DateUtils.getYears()
                + File.separator + DateUtils.getMonth() + File.separator + DateUtils.getDay() + File.separator + fileName;
    }

    public  String getFileType(String fileName) {
        String type = fileName.substring(fileName.lastIndexOf(".") + 1);
        return type;
    }

    /***
     * data:,文本数据
     data:text/plain,文本数据
     data:text/html,HTML代码
     data:text/html;base64,base64编码的HTML代码
     data:text/css,CSS代码
     data:text/css;base64,base64编码的CSS代码
     data:text/JavaScript,Javascript代码
     data:text/javascript;base64,base64编码的Javascript代码
     编码的gif图片数据
     编码的png图片数据
     编码的jpeg图片数据
     编码的icon图片数据
     */
    public  String getBase64FileType(String data) {
       String fileType = data.split(",")[0];
       System.out.println(fileType);
       if("data:image/png;base64".equals(fileType)){
           return "png";
       }
       if("data:image/gif;base64".equals(fileType)){
            return "gif";
       }
        if("data:image/jpeg;base64".equals(fileType)){
            return "jpeg";
        }
       throw new RuntimeException("对不起，请上传正确的文件格式[.png,.gif,.jpg]");
    }

    private Integer getBase64FileSize(String data){
        String str = data.split(",")[1];
        Integer  equalIndex= str.indexOf("=");
        if(str.indexOf("=")>0) {
            str=str.substring(0, equalIndex);
        }
        Integer strLength=str.length();
       return strLength-(strLength/8)*2;
    }

    private byte[] base64StrToByte(String data){
        byte[] b ;
        b = decode(data.split(",")[1]);
        for (int i = 0; i < b.length; ++i) {
            if (b[i] < 0) {// 调整异常数据
                b[i] += 256;
            }
        }
        return b;
    }


    public  String getEbookFileFolder(){
        return File.separator + "upload" + File.separator +"ebook" + File.separator + DateUtils.getYears()
                + File.separator + DateUtils.getMonth() + File.separator + DateUtils.getDay() ;
    }

    private synchronized void writeFile(byte[] bytes,File file) throws Exception{
        BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(file));
        stream.write(bytes);
        stream.close();
    }


    public static void  main(String[] args){
        UploadComponent uploadComponent = new UploadComponent();
        String s  = "1502176167115.png";
        System.out.println(s.contains("pngs"));
        uploadComponent.getBase64FileSize("");
    }
}
